/*
 * This class encapsulates information for one database statistic,
 * including the name and its value.
 * The value, which can not be directly set, is the average of all history values.
 * This feature is used for updating join selectivity factors.
 * Other statistics, however, are initialized and never changed in our experiments
 * and thus don't need this feature.
 * 
 * (c) Hongbin Kuang
 * 04/23/2009
 * V1.0
 */

package costEstimation;

import java.util.*;

public class Stat {
	// Prefixes of Stat's name field
	public static final String LT = "LT"; // Unit local processing time
	public static final String CT = "CT"; // Unit communication time
	public static final String LENGTH = "Length-"; // Length of an attribute
	public static final String CARD_DOM = "Card_Dom-"; // Cardinality of the domain of an attribute
	public static final String CARD_TABLE = "Card_Table-"; // Cardinality of a table
	public static final String CARD_ATTR = "Card_Attr-"; // Cardinality of the project of a table on an attribute
	public static final String JOIN_SELECT = "Join_Select-"; // Join selectivity factor
	public static final String MAX = "Max-"; // Maximum value of an attribute
	public static final String MIN = "Min-"; // Minimum value of an attribute
	
	public String name=null;
	private Double value=null;
	private ArrayList<Double> historyValues = new ArrayList<Double>();
		
	public Stat(String n)
	{
		name=n;
	}
	
	public double getValue()
	{
		if (value == null)
			return -1;
		
		return value.doubleValue();
	}

	// Update is done by adding new history value and re-calculating the average
	public boolean updateValue(double v)
	{
		if (historyValues.size() == 100) // Limit to 100 history values
			historyValues.remove(0);
		
		historyValues.add(new Double(v));
		
		Double sum = new Double(0);
		int k=historyValues.size();
		for (int i=0; i<k; i++)
			sum += historyValues.get(i);
		value=sum/k;
		
		return true;
	}
	
	// Function for comparing (only) the names of two Stat.
	// It's needed by the indexOf() function of ArrayList class.
	public boolean equals(Object o)
	{
		if (this == o)
			return true;
		
		if (o instanceof Stat)
			return name.equals(((Stat)o).name);
		
		return false;
	}
}
